package com.touch.jgloo.core;
import java.awt.*;
import java.util.*;
import com.sun.opengl.util.texture.*;
import com.touch.graphics.UV;
import com.touch.graphics.Point3D;
import com.touch.graphics.Renderable;
/**
 * JGLPolygon represents a polygon used in JGLObjects
 * @author Homicidal Monkey
 * @version 10.1.9
 * @since r461
 * @see com/touch/Licence
 */
public class JGLPolygon extends JGLBase implements Renderable, Cloneable
{
	//points of the polygon
	private final Vector<Point3D> 	points  = new Vector<Point3D>();
	//uv values of the polygon's points
	private final Vector<UV> 	uv 		= new Vector<UV>();
	//color of the polygon's points
	private final Vector<Color>		color 	= new Vector<Color>();
	//texture of the polygon
	public Texture texture;
	
	/**
	 * state used for the polygon
	 * @since r461
	 */
	public int renderState;
	/**
	 * start of render
	 * @since r461
	 */
	public boolean drawStart = true;
	/**
	 * stop of render
	 * @since 461
	 */
	public boolean drawEnd = true;
	/**
	 * Constructs a JGLPolygon without points
	 * @since r461
	 */
	public JGLPolygon(){}
	/**
	 * Constructs a JGLPolygon with a set of points	 * 
	 * @param points Number of points in the JGLPolygon
	 * @since r461
	 */
	public JGLPolygon(final int points)
	{
		//create a new point for each point specified
		for(int i = 0; i < points; i++)
		{
			//add the new point
			this.addPoint(new Point3D(0, 0, 0));
			//add a new UV value
			this.addUV(new UV(0, 0));
			//add a new Color value
			this.addColor(Color.WHITE);
		}
	}
	/**
	 * Creates a new polygon from an other Polygon. This just adds
	 * all of the points and UV values.
	 * @param polygon Polygon to take the points of
	 * @since r461
	 */
	public JGLPolygon(final JGLPolygon polygon)
	{		
		//add all of the points from the polygon
		for(Point3D p: polygon.points)
			this.points.add(p);
		//add all the UV values from the polygon
		for(UV uv: polygon.uv)
			this.uv.add(uv);
		//add all the Color values from the polygon
		for(Color color: polygon.color)
			this.addColor(color);
	}	
	/**
	 * Adds a point to the JGLPolygon
	 * @param point Point to add
	 * @since r461
	 */
	public void addPoint(final Point3D point)
	{
		//add the point to the Vector
		this.points.add(point);
	}
	/**
	 * Adds a point to the JGLPolygon
	 * @param uv UV to add
	 * @since r461
	 */
	public void addUV(final UV uv)
	{
		//add the UV Object to the Vector
		this.uv.add(uv);
	}
	/**
	 * Adds a Color to the JGLPolygon
	 * @param color Color to add
	 * @since r461
	 */
	public void addColor(final Color color)
	{
		//add the color
		this.color.add(color);
	}
	/**
	 * Gets the JGLPoint at the specified index
	 * @param pIndex Index of the point. The point must exist.
	 * @return JGLPoint at the specified index
	 * @since r461
	 */
	public Point3D getPoint(final int pIndex)
	{
		//returns the point
		return this.points.elementAt(pIndex);
	}
	/**
	 * Gets the JGLUV object at the specified point
	 * @param pIndex Index of the point
	 * @return JGLUV object representing the UV values at the point
	 * @since r461
	 */
	public UV getUV(final int pIndex)
	{
		//returns the UV
		return this.uv.elementAt(pIndex);
	}
	/**
	 * Gets the Color object of the specified point
	 * @param pIndex Index of the point
	 * @return Color object at the specified point
	 * @since r461
	 */
	public Color getColor(final int pIndex)
	{
		//return the Color object
		return this.color.elementAt(pIndex);
	}
	/**
	 * Returns the Texture of the JGLPolygon
	 * @return Texture of the JGLPolygon. If it was null, it will return the Blank texture.
	 * @since r461
	 */
	public Object getTexture()
	{
		//return the Texture
		return this.texture;
	}
	/**
	 * Sets the point of the JGLPolygon
	 * @param pIndex Index of the point
	 * @param point JGLObject for the point
	 * @since r461
	 */
	public void setPoint(final int pIndex, final Point3D point)
	{
		//set the point
		this.points.set(pIndex, point);
	}		
	/**
	 * Sets the UV value at a specific point
	 * @param pIndex Index of the point
	 * @param uv JGLUV object
	 * @since r461
	 */
	public void setUV(final int pIndex, final UV uv)
	{
		//overwrite the UV
		this.uv.set(pIndex, uv);
	}
	/**
	 * Sets the color at a specific Point
	 * @param pIndex Index of the point
	 * @param color Color for the point
	 * @since r461
	 */
	public void setColor(final int pIndex, final Color color)
	{
		//overwrite the color
		this.color.set(pIndex, color);
	}
	/**
	 * Sets the Texture of the JGLPolygon
	 * @param texture Texture
	 * @since r461
	 */
	public void setTexture(final Object texture)
	{
		//set the Texture
		this.texture = (Texture)texture;
	}
	/**
	 * Gets the number of points
	 * @return Number of points
	 * @since r461
	 */
	public synchronized int getPoints()
	{
		//return the number of points
		return this.points.size();
	}
	/**
	 * Gets the number of Colors
	 * @return Number of Colors
	 * @since r461
	 */
	public synchronized int getColors()
	{
		//return the number of Colors
		return this.color.size();
	}
	/**
	 * Gets the number of UV values
	 * @return Number of UV values
	 * @since r461
	 */
	public synchronized int getUV()
	{
		//return the number of UV values
		return this.uv.size();
	}
	public void render() 
	{
		//get the number of points
		final int points = this.getPoints();
		//get the number of colors
		final int colors = this.getColors();
		//get the number of uv
		final int uv	 = this.getUV();
		
		//render each point
		for(int i = 0; i < points; i++)
		{
			//if the color exists
			if(i <= colors)
			{
				//color the object
				final Color c = this.getColor(i);				
				GL_INSTANCE.glColor4f(
					c.getRed() / 255f, 
					c.getGreen() / 255f, 
					c.getBlue() / 255f, 
					c.getAlpha() / 255f);
			}
			//if the texture exists
			if(i <= uv && this.texture != null)
			{
				//texture the object
				final UV iUV = this.getUV(i);
				GL_INSTANCE.glTexCoord2f(iUV.u, iUV.v);
			}
			//if the point exists
			final Point3D p = this.getPoint(i);
			//draw the point
			GL_INSTANCE.glVertex3i(p.x, p.y, p.z);
		}
	}
	/**
	 * Overrides the "String toString()" method of JGLObject to better describe the JGLPolygon.
	 * @return String describing the JGLPolygon
	 * @since r461
	 */
	public String toString()
	{
		//set the beginning of the String
		String d = "JGLPolygon: ";
		//add onto it for each point.
		for(Point3D point: points)		
			d = d + point.toString();		
		return d;
	}
	public JGLPolygon clone()
	{
		final JGLPolygon clone = new JGLPolygon();
		
		for(Color cloneColor: this.color)		
			clone.addColor(cloneColor);	
		for(UV cloneUV: this.uv)
			clone.addUV(cloneUV.clone());
		for(Point3D clonePoint: this.points)
			clone.addPoint(clonePoint.clone());
		clone.texture = this.texture;
		clone.renderState = this.renderState;
		clone.drawEnd = this.drawEnd;
		clone.drawStart = this.drawStart;
		
		return clone;
	}
}
